package com.tangxz.comparison.test;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

/**
 * Description:
 * User: Administrator
 * Date: 2025/3/2 21:31
 */

@Aspect
@Component
@EnableAsync
@EnableAspectJAutoProxy
public class MethodCompareAspect {
    private static final Pattern METHOD_PATH_PATTERN =
            Pattern.compile("^([a-zA-Z_$][a-zA-Z\\d_$]*\\.)*[a-zA-Z_$][a-zA-Z\\d_$]*\\.[a-zA-Z_$][a-zA-Z\\d_$]*$");

    @Autowired
    private ResultComparator resultComparator;
    @Autowired
    private ApplicationContext applicationContext;

    @AfterReturning(pointcut = "@annotation(compareMethod)", returning = "result")
    public void afterReturning(JoinPoint joinPoint, CompareMethod compareMethod, Object result) {
        validateMethodPath(compareMethod.methodPath());

        String[] parts = compareMethod.methodPath().split("\\.(?=[^\\.]+$)");
        String className = parts[0];
        String methodName = parts[1];

        Object[] args = joinPoint.getArgs();
//        Object target = getTargetInstance(joinPoint.getTarget(), className);
        Object bean = applicationContext.getBean(getClass(className));
        resultComparator.compareAsync(bean, methodName, args, result);
    }

    private void validateMethodPath(String methodPath) {
        if (!METHOD_PATH_PATTERN.matcher(methodPath).matches()) {
            throw new IllegalArgumentException("Invalid method path format: " + methodPath);
        }
    }

    private Object getTargetInstance(Object originalTarget, String targetClassName) {
        try {
            Class<?> targetClass = Class.forName(targetClassName);
            if (targetClass.isInstance(originalTarget)) {
                return originalTarget;
            }
            // 如果是其他类的静态方法
            return null; // 需要根据实际情况处理
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Target class not found: " + targetClassName, e);
        }
    }
    private Class<?> getClass(String targetClassName) {
        try {
            return Class.forName(targetClassName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Target class not found: " + targetClassName, e);
        }
    }
}
